From 42c41d7bbdd604ef33baf1eb40780c06da93d0d4 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sun, 27 Jul 2014 13:39:51 +0200 Subject: [PATCH] scrolledwindow: Be smarter at invalidating overshoot areas The previous way to invalidate was meant to work on the overshoot window so it wouldn't be as taxing. Since the overshoot window is gone, this would invalidate way more than intended. So constrain invalidated areas to the sides where overshoot is happenning at that moment. https://bugzilla.gnome.org/show_bug.cgi?id=735223 --- gtk/gtkscrolledwindow.c | 56 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index fd090cb0d0..79f8cd8ddd 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -600,6 +600,53 @@ scrolled_window_drag_begin_cb (GtkScrolledWindow *scrolled_window, gtk_gesture_set_sequence_state (gesture, sequence, state); } +static void +gtk_scrolled_window_invalidate_overshoot (GtkScrolledWindow *scrolled_window) +{ + GtkAllocation child_allocation, allocation; + gint overshoot_x, overshoot_y; + GdkRectangle rect; + + if (!_gtk_scrolled_window_get_overshoot (scrolled_window, &overshoot_x, &overshoot_y)) + return; + + gtk_widget_get_allocation (GTK_WIDGET (scrolled_window), &allocation); + gtk_scrolled_window_relative_allocation (GTK_WIDGET (scrolled_window), + &child_allocation); + child_allocation.x += allocation.x; + child_allocation.y += allocation.y; + + if (overshoot_x != 0) + { + if (overshoot_x < 0) + rect.x = child_allocation.x; + else + rect.x = child_allocation.x + child_allocation.width - MAX_OVERSHOOT_DISTANCE; + + rect.y = child_allocation.y; + rect.width = MAX_OVERSHOOT_DISTANCE; + rect.height = child_allocation.height; + + gdk_window_invalidate_rect (gtk_widget_get_window (GTK_WIDGET (scrolled_window)), + &rect, TRUE); + } + + if (overshoot_y != 0) + { + if (overshoot_y < 0) + rect.y = child_allocation.y; + else + rect.y = child_allocation.y + child_allocation.height - MAX_OVERSHOOT_DISTANCE; + + rect.x = child_allocation.x; + rect.width = child_allocation.width; + rect.height = MAX_OVERSHOOT_DISTANCE; + + gdk_window_invalidate_rect (gtk_widget_get_window (GTK_WIDGET (scrolled_window)), + &rect, TRUE); + } +} + static void scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window, gdouble offset_x, @@ -611,6 +658,8 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window, GtkAdjustment *vadjustment; gdouble dx, dy; + gtk_scrolled_window_invalidate_overshoot (scrolled_window); + if (!priv->capture_button_press) { GdkEventSequence *sequence; @@ -636,8 +685,7 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window, dy, TRUE, FALSE); } - gdk_window_invalidate_rect (gtk_widget_get_window (GTK_WIDGET (scrolled_window)), - NULL, FALSE); + gtk_scrolled_window_invalidate_overshoot (scrolled_window); } static void @@ -2501,6 +2549,8 @@ scrolled_window_deceleration_cb (GtkWidget *widget, hadjustment = gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)); vadjustment = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)); + gtk_scrolled_window_invalidate_overshoot (scrolled_window); + if (data->hscrolling && gtk_kinetic_scrolling_tick (data->hscrolling, elapsed, &position)) { @@ -2525,7 +2575,7 @@ scrolled_window_deceleration_cb (GtkWidget *widget, return G_SOURCE_REMOVE; } - gdk_window_invalidate_rect (gtk_widget_get_window (widget), NULL, FALSE); + gtk_scrolled_window_invalidate_overshoot (scrolled_window); return G_SOURCE_CONTINUE; } -- 2.30.2